package ah.szxy.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 服务消费者控制器
 *
 * @author caohaiyang
 * @create 2020-09-09 下午 03:59
 */
@Controller
public class ConsumerProvider {

    @Autowired
    private DiscoveryClient discoveryClient;//用于进行服务的注册与发现


    @GetMapping("/discovery/{serviceName}")
    @ResponseBody
    public ResponseEntity<List<String>> discover (@PathVariable("serviceName") String serviceName){
        //通过服务的id or 名称得到服务的实例
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
        //判空
        if (instances == null || instances.isEmpty()) {
            return ResponseEntity.notFound().build();
        }

        //创建一个list集合,用于接收服务信息
        List<String> services = new ArrayList<>(instances.size());

        instances.forEach(e->{
            services.add(e.getHost() + ":" + e.getPort());
        });

        return ResponseEntity.ok(services);
    }



    @Autowired
    private RestTemplate restTemplate;

    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    /**
     * 远程调用测试
     * @param message 参数
     * @return
     */
    @GetMapping("/rpc1/{message}")
    public ResponseEntity rpv1(@PathVariable String message) {
        ResponseEntity<String> responseEntity = null;
        try{
            responseEntity = this.restTemplate.getForEntity(
                    // 调用服务的 url 地址
                    "http://localhost:8081/data/" + message,
                    // 调用服务的返回值类型
                    String.class
            );
        }catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body("远程调用失败");
        }
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return ResponseEntity.ok("远程调用成功，内容为：" + responseEntity.getBody());
        }
        return ResponseEntity.badRequest().body("远程调用失败");
    }


    /**
     * 远程调用测试2
     * @param message 参数
     * @return
     */
    @GetMapping("/rpc2/{message}")
    public ResponseEntity rpv2(@PathVariable String message) {
        List<ServiceInstance> instances = this.discoveryClient.getInstances("nacos-provider");
        ServiceInstance serviceInstance = instances.get(0);
        ResponseEntity<String> responseEntity = null;
        try{
            responseEntity = this.restTemplate.getForEntity(
                    // 调用服务的 url 地址
                    String.format("http://%s/data/%s", serviceInstance.getHost()+":"+serviceInstance.getPort(), message),
                    // 调用服务的返回值类型
                    String.class
            );
            System.out.println( String.format("http://%s/data/%s", serviceInstance.getHost()+":"+serviceInstance.getPort(), message));
        }catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body("远程调用失败");
        }
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return ResponseEntity.ok("远程调用成功，内容为：" + responseEntity.getBody());
        }
        return ResponseEntity.badRequest().body("远程调用失败");
    }


    /**
     * 远程调用测试3
     * @param message 参数
     * @return
     */
    @GetMapping("/rpc3/{message}")
    public ResponseEntity rpv3(@PathVariable String message) {
        List<ServiceInstance> instances = this.discoveryClient.getInstances("nacos-provider");
        ServiceInstance serviceInstance = loadBalance(instances);
        System.out.println("serviceInstance = " + serviceInstance);
        ResponseEntity<String> responseEntity = null;
        try{
            responseEntity = this.restTemplate.getForEntity(
                    // 调用服务的 url 地址
                    String.format("http://%s/data2/%s", serviceInstance.getHost()+":"+serviceInstance.getPort(), message),
                    // 调用服务的返回值类型
                    String.class
            );
        }catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body("远程调用失败");
        }
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return ResponseEntity.ok("远程调用成功，内容为：" + responseEntity.getBody());
        }
        return ResponseEntity.badRequest().body("远程调用失败");
    }


    /**
     * 随机从服务列表中选取一个服务地址
     * @param instances 服务列表
     * @return
     */
    private ServiceInstance loadBalance(List<ServiceInstance> instances) {
        Random random = new Random(System.currentTimeMillis());
        return instances.get(random.nextInt(instances.size()));
    }



    /**
     * 远程调用测试4
     * @param message 参数
     * @return
     */
    @GetMapping("/rpc4/{message}")
    public ResponseEntity rpv4(@PathVariable String message) {
        ResponseEntity<String> responseEntity = null;
        try{
            responseEntity = this.restTemplate.getForEntity(
                    // 调用服务的 url 地址
                    "http://nacos-provider/data2/{message}",
                    // 调用服务的返回值类型
                    String.class,
                    // 参数值
                    message
            );
        }catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body("远程调用失败");
        }
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return ResponseEntity.ok("远程调用成功，内容为：" + responseEntity.getBody());
        }
        return ResponseEntity.badRequest().body("远程调用失败");
    }
}